/*
 * Copyright (c) 2020 Nanjing Xiaoxiongpai Intelligent Technology Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdio.h>
#include <string.h>
#include <unistd.h>

#include "ohos_init.h"
#include "cmsis_os2.h"

#include "cJSON.h"
#include "lwip/sockets.h"

#include "iot_demo_def.h"

#include "iot_weather.h"
#include "iot_main.h"

#define CONFIG_TASK_PRIOR           25                        /* default task priority */
#define CONFIG_TASK_DEFAULT_STACKSIZE    0x1000             /* unit:bytes */

#define  GET_REQUEST_PACKAGE     \
         "GET http://www.tianqiapi.com/api/?version=v6&appid=%s&appsecret=%s\r\n\r\n"

#define  appid    "54612715"
#define  appsecret    "4dlrQLn8 "


#define WEATHER_IP_ADDR "120.27.2.251"
#define WEATHER_PORT    80

struct weather_str_info
{
    char *response;
    cJSON *root;
    cJSON *date;
    cJSON *city;
    cJSON *cur_temp;
    cJSON *high_temp;
    cJSON *low_temp;
    cJSON *humidity;
    cJSON *air_level;
    cJSON *wea;
    cJSON *wea_img;
    cJSON *air_pm25;
    cJSON *win;
    cJSON *win_speed;
};
struct weather_str_info info;

struct weather_info g_weatherInfo;
#define FLAGS_MSK1 0x00000001U

osEventFlagsId_t evt_id; /* event flags id */

void IotWeather_SetWeather(char *weather, char *temperature)
{
    if (weather == NULL || temperature == NULL) {
        return;
    }

    int weatherNum = IOT_WEATHER_NULL;

    if (strcmp("qing", weather)==0) {
        weatherNum = IOT_WEATHER_SUNNY;
    }
    if (strcmp("yin", weather)==0) {
        weatherNum = IOT_WEATHER_CLOUDY;
    }
    if (strcmp("yu", weather)==0) {
        weatherNum = IOT_WEATHER_RAIN;
    }
    if (strcmp("yun", weather)==0) {
        weatherNum = IOT_WEATHER_CLOUDY;
    }

    int temp = atoi(temperature);
    HILOG_ERROR(HILOG_MODULE_APP, "cur_temp %s ,temperature=%s,temp=%d--------------------\n\r",info.cur_temp->valuestring,temperature,temp);
    if( temp >= -50 && temp <= 50)
    {
        // IotMain_SetWeather(weatherNum, temp);
        g_weatherInfo.weatherIndex = weatherNum;
        g_weatherInfo.temperature = temp;
        IotMain_SetWeatherStatus(true);
       HILOG_ERROR(HILOG_MODULE_APP, "weatherIndex %d ,temperature=%d-------------------\n\r",g_weatherInfo.weatherIndex,g_weatherInfo.temperature);
    }
}

struct weather_info IotWeather_GetWeather( void)
{
    if ( (g_weatherInfo.temperature >= -50 && g_weatherInfo.temperature <= 50) && (g_weatherInfo.weatherIndex >= IOT_WEATHER_NULL && g_weatherInfo.weatherIndex <= IOT_WEATHER_SNOW) ) {
        return g_weatherInfo;
    }
}

void IotWeather_Task(void)
{
    char GetRequestBuf[256] = {0};
    static char WeatherRecvBuf[1024*4] = {0};

    g_weatherInfo.weatherIndex = IOT_WEATHER_NULL;
    g_weatherInfo.temperature = 0;

    evt_id = osEventFlagsNew(NULL);
    if (evt_id == NULL)
    {
        HILOG_ERROR(HILOG_MODULE_APP, "Falied to create EventFlags!\n");
    }

    while (1)
    {
        int  connect_status = 0;
		int ClientSock = -1;
        
        /* 设置要访问的服务器的信息 */
        struct sockaddr_in  ServerSockAddr;
        memset(&ServerSockAddr, 0, sizeof(ServerSockAddr));            /* 每个字节都用0填充 */
        ServerSockAddr.sin_family = AF_INET;                          /* IPv4 */
        ServerSockAddr.sin_addr.s_addr = inet_addr(WEATHER_IP_ADDR);  /* 天气服务器IP */
        ServerSockAddr.sin_port = htons(WEATHER_PORT);                 /*  端口 */
        
        /* 创建客户端socket */
        if (-1 == (ClientSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)))
        {
            printf("socket error!\n");
            exit(1);
        }

        /* 连接服务端 */
        if (-1 == (connect_status = connect(ClientSock, (struct sockaddr*)&ServerSockAddr, sizeof(struct sockaddr))))
        {
            printf("connect error!\n");
            exit(1);
        }
        
        /* 组合GET请求包 */
        sprintf(GetRequestBuf, GET_REQUEST_PACKAGE, appid, appsecret);

        /* 发送数据到服务端 */
        send(ClientSock, GetRequestBuf, strlen(GetRequestBuf), 0);
            
        /* 接受服务端的返回数据 */
        recv(ClientSock, WeatherRecvBuf, 1024*4, 0);
        HILOG_ERROR(HILOG_MODULE_APP, "ClientSock %s \n\r",WeatherRecvBuf);

        int retSts = false;
        if (strstr(WeatherRecvBuf,"errcode") == NULL) {
            HILOG_ERROR(HILOG_MODULE_APP, "no find error msg");
            retSts = true;
            info.root  = cJSON_Parse(WeatherRecvBuf); /* 解析JSON数据包 */
        } else {
            retSts = false;
            HILOG_ERROR(HILOG_MODULE_APP, "find error msg");
        }
        
        if (info.root  != NULL)  /* 检测JSON数据包是否存在语法上的错误，返回NULL表示数据包无效 */
        {

            info.date = cJSON_GetObjectItem(info.root, "date");
            info.city = cJSON_GetObjectItem(info.root, "city");
            info.cur_temp = cJSON_GetObjectItem(info.root, "tem");
            info.high_temp = cJSON_GetObjectItem(info.root, "tem1");
            info.low_temp = cJSON_GetObjectItem(info.root, "tem2");
            info.humidity = cJSON_GetObjectItem(info.root, "humidity");
            info.wea = cJSON_GetObjectItem(info.root, "wea");             
            info.wea_img = cJSON_GetObjectItem(info.root, "wea_img");
            info.air_pm25 = cJSON_GetObjectItem(info.root, "air_pm25");
            info.air_level = cJSON_GetObjectItem(info.root, "air_level");
            info.win = cJSON_GetObjectItem(info.root, "win");
            info.win_speed = cJSON_GetObjectItem(info.root, "win_speed");
            HILOG_ERROR(HILOG_MODULE_APP, "date : %s, cur_temp : %s, humidity : %s, wea_img : %s  air_pm25: %s\n",
                    info.date->valuestring, info.cur_temp->valuestring,
                    info.humidity->valuestring, info.wea_img->valuestring, info.air_pm25->valuestring);

            /*date : 2021-12-22, cur_temp : 19, humidity : 72%, wea_img : yun  air_pm25: 38*/
            IotWeather_SetWeather(info.wea_img->valuestring, info.cur_temp->valuestring);
        
            cJSON_Delete(info.root); /* 释放cJSON_Parse()分配出来的内存空间 */
        }

        if (retSts) {
            /* 显示天气 */
            sleep(5);
        } else {
        }
  
        /* 清空缓冲区 */
        memset(GetRequestBuf, 0, 256);   
        memset(WeatherRecvBuf, 0, 1024*4);      
        /* 关闭套接字 */
        closesocket(ClientSock);

        osEventFlagsWait(evt_id, FLAGS_MSK1, osFlagsWaitAny, osWaitForever);
    }
}

#define CONFIG_TASK_LEVEL                20

void IotWeather_TaskCreate(void)
{
    /* Create a task to handle weather communication */

    osThreadAttr_t attr = {0};
    attr.stack_size = 1024*4;
    attr.priority = CONFIG_TASK_LEVEL;
    attr.name = "iot_weather_task";
    if (osThreadNew((osThreadFunc_t)IotWeather_Task, NULL, &attr) == NULL) {
        HILOG_ERROR(HILOG_MODULE_APP, "Failed to create IotWeather_Task\r\n");
    }
}

